from typing import Optional, List, Dict, Any

from sqlalchemy.orm import sessionmaker

from db.dao.base_dao import BaseDao
from db.log import log
from db.model.device import Device


class DeviceDao(BaseDao):
    def __init__(self, db_config):
        super().__init__(db_config)

    @classmethod
    def add_device(cls, device_name: str, ip: str, port: int, protocol: str) -> bool:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                device = Device(name=device_name, ip=ip, port=port, protocol=protocol)
                session.add(device)
                return True
            except Exception as e:
                log.error(e)
                return False

    @classmethod
    def edit_device(cls, device_id: int, device_name: str, ip: str, port: int, protocol: str) -> bool:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                device = session.query(Device).filter(Device.id == device_id).first()
                if device:
                    device.name = device_name
                    device.ip = ip
                    device.port = port
                    device.protocol = protocol
                    return True
                else:
                    return False
            except Exception as e:
                log.error(e)
                return False

    @classmethod
    def delete_device(cls, device_name: str) -> bool:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                device = session.query(Device).filter(Device.name == device_name).first()
                if device:
                    session.delete(device)
                    return True
                else:
                    return False
            except Exception as e:
                log.error(e)
                return False

    @classmethod
    def get_device_by_id(cls, device_id) -> Dict[str, Any]:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                result = session.query(Device).filter(Device.id == device_id).first()
                return {"name": result.name, "ip": result.ip, "port": result.port,
                        "protocol": result.protocol}
            except Exception as e:
                log.error(e)
                return {}

    @classmethod
    def get_device_by_name(cls, device_name) -> Dict[str, Any]:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                result = session.query(Device).filter(Device.name == device_name).first()
                return {"name": result.name, "ip": result.ip, "port": result.port,
                        "protocol": result.protocol}
            except Exception as e:
                log.error(e)
                return {}

    @classmethod
    def is_device_exist(cls, device_name: str) -> bool:
        Session = sessionmaker(cls.db_config.engine)
        with Session.begin() as session:
            try:
                device = session.query(Device).filter(Device.name == device_name).first()
                if device:
                    return True
                else:
                    return False
            except Exception as e:
                log.error(e)
                return False

    def get_device_list(self) -> List[Dict[str, Any]]:
        Session = sessionmaker(self.db_config.engine)
        with Session.begin() as session:
            try:
                result = session.query(Device).order_by(Device.id).all()
                return [{"id": device.id, "name": device.name, "ip": device.ip, "port": device.port,
                         "protocol": device.protocol} for device in result]
            except Exception as e:
                log.error(e)
                return []
